<template>
  <div class="sh-table">
    <sh-search
      v-if="isShowSearch"
      ref="ShSearchRef"
      :configs="getFormConfig.configs"
      :centerType="getFormConfig.centerType"
      :labelWidth="getFormConfig.labelWidth"
      @search="onSearch"
      @reset="onReset"
    />

    <div class="sh-table-container">
      <sh-table-operation>
        <template #tableOperation>
          <slot name="tableOperation">
            <div class="table-toolbar" v-if="$slots.toolbtn || title">
              <sh-title :prefix="showPrefix">{{ title }}</sh-title>
              <sh-table-toolbar v-if="$slots.toolbtn">
                <template #toolbtn>
                  <slot name="toolbtn" />
                </template>
              </sh-table-toolbar>
            </div>
          </slot>
        </template>
      </sh-table-operation>

      <Table
        ref="ShTableRef"
        v-bind="getBindValues($attrs)"
        :data="getData"
        :columns="getViewColumns"
        :loading="getLoading"
        @on-select="$event => onSelectChange($event, 'select')"
        @on-select-cancel="$event => onSelectChange($event, 'cancel')"
        @on-select-all="$event => onSelectChange($event, 'all')"
        @on-select-all-cancel="$event => onSelectChange($event, 'allCancel')"
      >
        <template v-for="item in getColumsSlots" #[item.slot]="{ row, index }">
          <slot :name="item.slot" :row="row" :index="index" />
        </template>
      </Table>

      <Page
        v-if="showPage"
        size="small"
        class-name="sh-page"
        :model-value="paginationInfo.current"
        :page-size="paginationInfo.pageSize"
        :page-size-opts="paginationInfo.pageSizeOpts"
        :show-sizer="paginationInfo.showSizer"
        :show-elevator="paginationInfo.showElevator"
        :show-total="paginationInfo.showTotal"
        :total="paginationInfo.total"
        @on-change="handleOnChange"
        @on-page-size-change="handleOnSizeChange"
      />
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, watch } from 'vue';
import ShTableToolbar from './table-toolbar.vue';
import ShTableOperation from './table-operation.vue';
import { useComputed } from './utils/useComputed';
import { useSearch } from './utils/useSearch';
import { useHandlePage } from './utils/useHandlePage';
import { useHandleSelect } from './utils/useHandleSelect';
import { useLoading } from './utils/useLoading';
import { useDependencyInjection } from '../../utils/useDependencyInjection';

const props = defineProps({
  showSearch: {
    type: Boolean,
    default: true,
  },
  formConfigs: {
    type: Object,
    default: () => {
      return {
        configs: [],
        labelWidth: 100,
        centerType: false,
      };
    },
  },
  title: {
    type: String,
  },
  showPrefix: {
    type: Boolean,
    default: false,
  },
  data: {
    type: Array,
    default: () => {
      return [];
    },
  },
  columns: {
    type: Array,
    default: () => {
      return [];
    },
  },
  pagination: {
    type: Object,
    default: () => {
      return {};
    },
  },
  showPage: {
    type: Boolean,
    default: true,
  },
  loading: {
    type: Boolean,
    default: false,
  },
});
const emits = defineEmits([
  'on-select-change',
  'page-change',
  'page-size-change',
  'tabs-change',
  'on-search',
  'on-reset',
  'register',
]);
const tabIndex = ref(0);

const { getData, getColumsSlots, getViewColumns, getBindValues } = useComputed(props);

const { ShTableRef, onSelectChange, selectAll } = useHandleSelect(emits);

const { getLoading } = useLoading(props);

const { handleOnChange, handleOnSizeChange, paginationInfo, resetPage } = useHandlePage(props, emits);

const { ShSearchRef, isShowSearch, getFormConfig, onSearch, onReset, setSearchValue, getSearchValue } = useSearch(
  props,
  emits,
  paginationInfo,
  resetPage
);

defineExpose({ setSearchValue, getSearchValue });

const { setProvide } = useDependencyInjection();
setProvide(['tabs', 'tabIndex', 'page'], {
  tabs: props.tabs,
  tabIndex: tabIndex,
  page: paginationInfo,
});

watch(tabIndex, index => {
  tabIndex.value = index;
  resetPage();
  emits('tabs-change', index);
});

const tableMethods = {
  selectAll,
  setSearchValue,
  getSearchValue,
  onSearch,
  onReset,
  resetPage,
  handleOnChange,
  handleOnSizeChange,
};

onMounted(() => {
  emits('register', tableMethods);
});
</script>
